<script setup lang="ts">
  import IconSelect from '@/components/icon-select/index.vue';
  import { createMenu, editMenu, getMenuDetail, getMenuTree } from '@/api/menu';
  import { MenuData, MenuTree } from '@/api/menu/types';
  import { computed, onMounted, Ref, ref, watch, watchEffect } from 'vue';
  import { FormInstance, Message } from '@arco-design/web-vue';
  import { detail, selectKeyList } from '@/api/locale';
  import { debounce } from 'lodash';

  defineProps({
    dialogVisiable: {
      type: Boolean,
      default() {
        return false;
      },
    },
  });

  const emit = defineEmits(['dialogStatus', 'saveSuccess']);
  const formRef = ref();
  const options: Ref<string[]> = ref([]);
  const loading = ref(false);
  // 添加表单实体
  const addForm: Ref<MenuData> = ref({
    id: undefined,
    menuType: 0,
    menuParentId: '0',
    menuName: '',
    path: '',
    routerName: '',
    order: 0,
    icon: '',
    permission: '',
    component: '@/layout/default-layout.vue',
    requiresAuth: true,
    locale: '',
    hideInMenu: false,
    hideChildrenInMenu: false,
    noAffix: false,
    ignoreCache: true,
    activeMenu: '',
  });
  const saveId: Ref<number | undefined> = ref();
  // 动态设置 component 属性
  watch(
    () => addForm.value.menuType,
    (newMenuType) => {
      if (saveId.value === undefined) {
        addForm.value.component =
          newMenuType === 0 ? '@/layout/default-layout.vue' : '';
      }
    },
    {
      immediate: false, // 默认不立即执行
      flush: 'sync', // 同步执行
    },
  );
  const rules: FormInstance['rules'] = {
    menuName: [
      {
        required: true,
        message: '菜单名称不能为空',
      },
    ],
    path: [
      {
        required: true,
        message: '路由不能为空',
      },
    ],
    routerName: [
      {
        required: true,
        message: '路由名称不能为空',
      },
    ],
    permission: [
      {
        required: true,
        message: '权限标识不能为空',
      },
    ],
    component: [
      {
        required: true,
        message: '组件路径不能为空',
      },
    ],
    locale: [
      {
        required: true,
        message: '国际化标识不能为空',
      },
    ],
  };
  // 根据选中的菜单类型 计算不同的校检规则
  const formRules = computed(() => {
    if ([0, 1].includes(addForm.value.menuType)) {
      return rules as FormInstance['rules'];
    }
    const { menuName, permission } = rules;
    return { menuName, permission } as FormInstance['rules'];
  });
  // 表单菜单类型计算
  const computerMenuType = computed(() => {
    return addForm.value.menuType !== 2 ? '菜单名称' : '按钮名称';
  });
  // 表单菜单树列表
  const menuTreeData = ref<MenuTree[]>([]);
  // 获取菜单树
  const getTree = async () => {
    const result = await getMenuTree(false);
    menuTreeData.value = result.data;
  };
  // 获取国际化键名列表
  const getKeyList = async () => {
    const result = await selectKeyList('');
    options.value = result.data;
  };
  onMounted(() => getTree());
  onMounted(() => getKeyList());
  const inputValue = debounce(async (value: string) => {
    loading.value = true;
    window.setTimeout(async () => {
      const result = await selectKeyList(value);
      options.value = result.data;
      loading.value = false;
    }, 300);
  }, 400); // 400ms 的延迟时间
  watch(
    () => addForm.value.locale,
    async () => {
      const result = await detail(addForm.value.locale);
      const { chineseMessage, englishMessage } = result.data;
      addForm.value.menuName = chineseMessage;
    },
  );
  // 保存
  const handleSave = async () => {
    try {
      const isInvalid = await formRef.value?.validate();
      if (isInvalid) return false;
      // 保存和编辑
      if (saveId.value) {
        await editMenu(addForm.value);
      } else {
        delete addForm.value.id;
        await createMenu(addForm.value);
      }
      // 关闭对话框
      emit('saveSuccess');
      Message.success('保存成功');
      // 重新获取菜单树
      await getTree();
      return true;
    } catch (error) {
      return false;
    }
  };
  // 编辑
  const handleEdit = async (id: number) => {
    await getMenuDetail(id).then((result) => {
      saveId.value = id;
      addForm.value = result.data;
    });
  };
  // 点击关闭-取消按钮后触发
  const handleCancel = () => {
    emit('dialogStatus', false);
  };
  // 对话框关闭后触发
  const handleClose = () => {
    formRef.value.resetFields();
    saveId.value = undefined;
  };
  // const handleSearch = async (value: string) => {
  //   if (value) {
  //     loading.value = true;
  //     const result = await selectKeyList(value);
  //     options.value = result.data;
  //     loading.value = false;
  //   } else {
  //     options.value = [];
  //   }
  // };
  // 暴露方法
  defineExpose({
    handleEdit,
  });
</script>

<template>
  <a-modal
    :visible="dialogVisiable"
    title-align="start"
    :ok-text="$t('modal.operation.save')"
    :cancel-text="$t('modal.operation.cancel')"
    unmount-on-close
    :modal-style="{ maxWidth: '625px' }"
    width="90%"
    @before-ok="handleSave"
    @close="handleClose"
    @cancel="handleCancel"
  >
    <template #title
      >{{
        saveId
          ? $t('searchTable.operation.edit')
          : $t('searchTable.operation.create')
      }}
    </template>
    <a-form ref="formRef" :rules="formRules" :model="addForm" auto-label-width>
      <a-form-item field="menuType" label="菜单类型">
        <a-radio-group
          v-model="addForm.menuType"
          type="button"
          :disabled="!!saveId"
        >
          <a-radio :value="0">目录</a-radio>
          <a-radio :value="1">菜单</a-radio>
          <a-radio :value="2">按钮</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item field="menuParentId" label="上级菜单">
        <a-tree-select
          v-model="addForm.menuParentId"
          :data="menuTreeData"
          placeholder="请选择"
        />
      </a-form-item>
      <a-form-item
        v-if="addForm.menuType !== 2"
        field="locale"
        label="键名"
        tooltip="一级菜单名（语言包键名）"
      >
        <a-select
          v-model="addForm.locale"
          :options="options"
          :loading="loading"
          allow-search
          allow-clear
          placeholder="请输入国际化键名，例如 menu.system.role"
          :filter-option="false"
          :show-extra-options="false"
          :virtual-list-props="{ threshold: 20, fixedSize: true, height: 180 }"
          @input-value-change="inputValue"
        />
      </a-form-item>
      <a-form-item field="menuName" :label="computerMenuType">
        <a-input
          v-model="addForm.menuName"
          allow-clear
          :placeholder="`请输入${computerMenuType}`"
          :readonly="addForm.menuType !== 2"
        ></a-input>
      </a-form-item>
      <a-form-item v-if="addForm.menuType !== 2" field="icon" label="图标">
        <IconSelect v-model="addForm.icon"></IconSelect>
      </a-form-item>
      <a-form-item v-if="addForm.menuType !== 2" field="path" label="路由">
        <a-input
          v-model="addForm.path"
          allow-clear
          placeholder="请输入路由，例如 /system/user"
        ></a-input>
      </a-form-item>
      <a-form-item
        v-show="addForm.menuType !== 2"
        field="routerName"
        label="路由名称"
      >
        <a-input
          v-model="addForm.routerName"
          allow-clear
          placeholder="请输入路由名称，例如 User"
        ></a-input>
      </a-form-item>
      <a-form-item field="permission" label="权限标识">
        <a-input
          v-model="addForm.permission"
          allow-clear
          placeholder="请输入权限标识，例如 system:user:add"
        ></a-input>
      </a-form-item>
      <a-form-item
        v-if="addForm.menuType !== 2"
        field="component"
        label="组件路径"
      >
        <a-input
          v-model="addForm.component"
          allow-clear
          :readonly="addForm.menuType === 0"
          placeholder="请输入组件路径，例如 @/views/system/user/index.vue"
        ></a-input>
      </a-form-item>
      <a-form-item
        field="order"
        label="排序"
        tooltip="排序路由菜单项，如果设置该值，值越高，越靠前"
      >
        <a-input-number
          v-model="addForm.order"
          :style="{ width: '150px' }"
          mode="button"
        />
      </a-form-item>
      <a-row :gutter="16">
        <a-col
          v-if="addForm.menuType !== 2"
          :xs="12"
          :sm="12"
          :md="12"
          :lg="12"
          :xl="12"
          :xxl="12"
        >
          <a-form-item
            field="hideInMenu"
            label="是否隐藏"
            tooltip="如果设置为隐藏，左侧菜单中将隐藏该项"
          >
            <a-switch
              v-model="addForm.hideInMenu"
              :checked-value="false"
              :unchecked-value="true"
              checked-text="否"
              unchecked-text="是"
              type="round"
            />
          </a-form-item>
        </a-col>
        <a-col
          v-if="addForm.menuType !== 2"
          :xs="12"
          :sm="12"
          :md="12"
          :lg="12"
          :xl="12"
          :xxl="12"
        >
          <a-form-item
            label="是否缓存"
            field="ignoreCache"
            tooltip="如果设置为否，页面将不会被缓存"
          >
            <a-switch
              v-model="addForm.ignoreCache"
              :checked-value="true"
              :unchecked-value="false"
              checked-text="否"
              unchecked-text="是"
              type="round"
            />
          </a-form-item>
        </a-col>
        <a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12" :xxl="12">
          <a-form-item
            field="requiresAuth"
            label="是否认证"
            tooltip="是否需要登录鉴权"
          >
            <a-switch
              v-model="addForm.requiresAuth"
              :checked-value="true"
              :unchecked-value="false"
              checked-text="是"
              unchecked-text="否"
              type="round"
            />
          </a-form-item>
        </a-col>
        <a-col
          v-if="addForm.menuType !== 2"
          :xs="12"
          :sm="12"
          :md="12"
          :lg="12"
          :xl="12"
          :xxl="12"
        >
          <a-form-item
            field="hideChildrenInMenu"
            label="下级菜单"
            tooltip="如果设置为隐藏，下级菜单将不会显示"
          >
            <a-switch
              v-model="addForm.hideChildrenInMenu"
              :checked-value="false"
              :unchecked-value="true"
              checked-text="显示"
              unchecked-text="隐藏"
              type="round"
            />
          </a-form-item>
        </a-col>
        <a-col
          v-if="addForm.menuType === 1"
          :xs="24"
          :sm="24"
          :md="24"
          :lg="24"
          :xl="24"
          :xxl="24"
        >
          <a-form-item
            field="noAffix"
            label="导航栏"
            tooltip="如果设置为隐藏，标签将不会添加到tab-bar中"
          >
            <a-switch
              v-model="addForm.noAffix"
              :checked-value="false"
              :unchecked-value="true"
              checked-text="显示"
              unchecked-text="隐藏"
              type="round"
            />
          </a-form-item>
        </a-col>
      </a-row>
    </a-form>
  </a-modal>
</template>

<style scoped lang="less"></style>
